/* 
* DisplayHandler.cpp
*
* Created: 10/4/2013 7:38:59 PM
* Author: brodzki
*/

#include "DisplayHandler.h"

void DisplayHandler::out_nibble(unsigned char nibble_to_write)
{
	if(nibble_to_write & 0x01)
		config_.db4_port.set_bit(config_.db4_bit);
	else
		config_.db4_port.unset_bit(config_.db4_bit);

	if(nibble_to_write & 0x02)
		config_.db5_port.set_bit(config_.db5_bit);
	else
		config_.db5_port.unset_bit(config_.db5_bit);

	if(nibble_to_write & 0x04)
		config_.db6_port.set_bit(config_.db6_bit);
	else
		config_.db6_port.unset_bit(config_.db6_bit);

	if(nibble_to_write & 0x08)
		config_.db7_port.set_bit(config_.db7_bit);
	else
		config_.db7_port.unset_bit(config_.db7_bit);
}

void DisplayHandler::write(unsigned char data)
{
	config_.e_port.set_bit(config_.e_bit);
	out_nibble(data >> 4);
	config_.e_port.unset_bit(config_.e_bit);
	config_.e_port.set_bit(config_.e_bit);
	out_nibble(data);
	config_.e_port.unset_bit(config_.e_bit);
	_delay_us(50);
}

void DisplayHandler::write_command(unsigned char command)
{
	config_.rs_port.unset_bit(config_.rs_bit);
	write(command);
}

void DisplayHandler::write_data(unsigned char data)
{
	config_.rs_port.set_bit(config_.rs_bit);
	write(data);
}

void DisplayHandler::write_text(char * text)
{
	while(*text)
		write_data(*text++);
}

void DisplayHandler::go_to(unsigned char x, unsigned char y)
{
	write_command(Commands::ddram_set | (x + (0x40 * y)));
}

void DisplayHandler::clear()
{
	write_command(Commands::clear);
	_delay_ms(2);
}

void DisplayHandler::home()
{
	write_command(Commands::home);
	_delay_ms(2);
}

void DisplayHandler::initialize()
{
	unsigned char i;
	
	// direction
	config_.db4_ddr.set_bit(config_.db4_bit);
	config_.db5_ddr.set_bit(config_.db5_bit);
	config_.db6_ddr.set_bit(config_.db6_bit);
	config_.db7_ddr.set_bit(config_.db7_bit);
	config_.e_ddr.set_bit(config_.e_bit);
	config_.rs_ddr.set_bit(config_.rs_bit);
	
	// stabilization
	_delay_ms(15);
	
	config_.rs_port.unset_bit(config_.rs_bit);
	config_.e_port.unset_bit(config_.e_bit);

	for(i = 0; i < 3; ++i)
	{
		 // 8 bit mode
		config_.e_port.set_bit(config_.e_bit);		
		out_nibble(0x03);	
		config_.e_port.unset_bit(config_.e_bit);		
		_delay_ms(5);
	}

	// 4 bit mode
	config_.e_port.set_bit(config_.e_bit);
	out_nibble(0x02);
	config_.e_port.unset_bit(config_.e_bit);

	_delay_ms(1);
	write_command(Commands::function_set | Commands::font5x7 | Commands::two_line | Commands::four_bit);
	write_command(Commands::display_on_off | Commands::display_off);
	write_command(Commands::clear); // clear DDRAM
	_delay_ms(2);
	write_command(Commands::entry_mode | Commands::em_shift_cursor | Commands::em_increment);
	write_command(Commands::display_on_off | Commands::display_on | Commands::cursor_on | Commands::cursor_noblink);
}
